home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / umoria / io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-28  |  10.7 KB  |  581 lines

  1. #include <curses.h>
  2. #include <sys/types.h>
  3. #include <sys/ioctl.h>
  4. #include <sys/file.h>
  5.  
  6. #include "constants.h"
  7. #include "config.h"
  8. #include "types.h"
  9. #include "externs.h"
  10.  
  11. #ifdef USG
  12. #include <string.h>
  13. #else
  14. #include <strings.h>
  15. #include <sgtty.h>
  16. #include <sys/wait.h>
  17. #endif
  18.  
  19. #ifdef sun   /* correct SUN stupidity in the stdio.h file */
  20. char *sprintf();
  21. #endif
  22.  
  23. vtype pad_output;   /* static output string for the pad function */
  24.  
  25. char *getenv();
  26.  
  27. vtype old_msg[SAVED_MSGS];      /* Last messages      */
  28. int last_message = 0;           /* Number of last msg generated in old_msg */
  29. int last_displayed_msg = 0;     /* Number of last msg printed (^M) */
  30. int repeating_old_msg = 0;      /* flag which lets repeat_msg call msg_print */
  31.  
  32. /* value of msg flag at start of turn */
  33. extern int save_msg_flag;
  34.  
  35. #ifdef USG
  36. void exit();
  37. unsigned sleep();
  38. #endif
  39. #ifdef ultrix
  40. void exit();
  41. void sleep();
  42. #endif
  43.  
  44. #ifdef USG
  45. /* no local special characters */
  46. #else
  47. struct ltchars save_special_chars;
  48. #endif
  49.  
  50. /* initializes curses routines */
  51. init_curses()
  52. {
  53. #ifdef USG
  54.   /* no local special characters */
  55. #else
  56.   struct ltchars buf;
  57. #endif
  58.  
  59. #ifdef USG
  60.   if (initscr() == NULL)
  61. #else
  62.   if (initscr() == ERR)
  63. #endif
  64.     {
  65.       (void) printf("error allocating screen in curses package\n");
  66.       exit_game();
  67.     }
  68.   clear();
  69. #ifdef USG
  70.   saveterm();
  71. #endif
  72. #if defined(ultrix)
  73.   crmode();
  74. #else
  75.   cbreak();
  76. #endif
  77.   noecho();
  78. #ifndef BUGGY_CURSES
  79.   nonl();
  80. #endif
  81.   /* save old settings of the local special characters */
  82. #ifdef USG
  83.   /* no local special characters */
  84. #else
  85.   (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
  86.   /* disable all of the local special characters except the suspend char */
  87.   /* have to disable ^Y for tunneling */
  88.   buf.t_suspc = (char)26;  /* control-Z */
  89.   buf.t_dsuspc = (char)-1;
  90.   buf.t_rprntc = (char)-1;
  91.   buf.t_flushc = (char)-1;
  92.   buf.t_werasc = (char)-1;
  93.   buf.t_lnextc = (char)-1;
  94.   (void) ioctl(0, TIOCSLTC, (char *)&buf);
  95. #endif
  96. }
  97.  
  98.  
  99. /* Dump IO to buffer                    -RAK-    */
  100. put_buffer(out_str, row, col)
  101. char *out_str;
  102. int row, col;
  103. {
  104.   vtype tmp_str;
  105.  
  106.   if (mvaddstr(row, col, out_str) == ERR)
  107.     {
  108.       (void) sprintf(tmp_str, "error row = %d col = %d\n", row, col);
  109.       prt(tmp_str, 0, 0);
  110.       /* wait so user can see error */
  111.       (void) sleep(2);
  112.     }
  113. }
  114.  
  115.  
  116. /* Dump the IO buffer to terminal            -RAK-    */
  117. put_qio()
  118. {
  119.   refresh();
  120. }
  121.  
  122.  
  123. shell_out()
  124. {
  125.   int val;
  126.   char *str;
  127. #ifdef USG
  128.   /* no local special characters */
  129. #else
  130.   struct ltchars buf;
  131. #endif
  132.  
  133.   /* clear screen and print 'exit' message */
  134.   clear_screen(0, 0);
  135.   prt("[Entering shell, type 'exit' to resume your game]\n",0,0);
  136.   put_qio();
  137.  
  138. #ifndef BUGGY_CURSES
  139.   nl();
  140. #endif
  141. #if defined(ultrix)
  142.   nocrmode();
  143. #else
  144.   nocbreak();
  145. #endif
  146.   echo();
  147.   ignore_signals();
  148.   val = fork();
  149.   if (val == 0)
  150.     {
  151.       default_signals();
  152. #ifdef USG
  153.       /* no local special characters */
  154.       resetterm();
  155. #else
  156.       (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  157. #endif
  158.       /* close scoreboard descriptor */
  159.       (void) close(highscore_fd);
  160.       if (str = getenv("SHELL"))
  161.     (void) execl(str, str, (char *) 0);
  162.       else
  163.     (void) execl("/bin/sh", "sh", (char *) 0);
  164.       msg_print("Cannot execute shell");
  165.       exit(1);
  166.     }
  167.   if (val == -1)
  168.     {
  169.       msg_print("Fork failed. Try again.");
  170.       return;
  171.     }
  172. #ifdef USG
  173.   (void) wait((int *) 0);
  174. #else
  175.   (void) wait((union wait *) 0);
  176. #endif
  177.   restore_signals();
  178.   /* restore the cave to the screen */
  179.   really_clear_screen();
  180.   draw_cave();
  181. #if defined(ultrix)
  182.   crmode();
  183. #else
  184.   cbreak();
  185. #endif
  186.   noecho();
  187. #ifndef BUGGY_CURSES
  188.   nonl();
  189. #endif
  190.   /* disable all of the local special characters except the suspend char */
  191.   /* have to disable ^Y for tunneling */
  192. #ifdef USG
  193.   /* no local special characters */
  194. #else
  195.   buf.t_suspc = (char)26;  /* control-Z */
  196.   buf.t_dsuspc = (char)-1;
  197.   buf.t_rprntc = (char)-1;
  198.   buf.t_flushc = (char)-1;
  199.   buf.t_werasc = (char)-1;
  200.   buf.t_lnextc = (char)-1;
  201.   (void) ioctl(0, TIOCSLTC, (char *)&buf);
  202. #endif
  203. }
  204.  
  205. exit_game()
  206. {
  207.   /* restore the saved values of the local special chars */
  208.   put_qio();    /* Dump any remaining buffer    */
  209.   endwin();     /* exit curses */
  210.   echo();
  211. #ifndef BUGGY_CURSES
  212.   nl();
  213. #endif
  214. #if defined(ultrix)
  215.   nocrmode();
  216. #else
  217.   nocbreak();
  218. #endif
  219. #ifdef USG
  220.   /* no local special characters */
  221.   resetterm();
  222. #else
  223.   (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  224. #endif
  225.   exit(0);    /* exit from game        */
  226. }
  227.  
  228.  
  229. /* Gets single character from keyboard and returns        */
  230. inkey(ch)
  231. char *ch;
  232. {
  233.   put_qio();            /* Dump IO buffer        */
  234.   *ch = getch();
  235.   msg_flag = FALSE;
  236. }
  237.  
  238.  
  239. /* Flush the buffer                    -RAK-    */
  240. flush()
  241. {
  242. #ifdef USG
  243.   (void) ioctl(0, TCFLSH, 0);  /* flush the input queue */
  244. #else
  245.   int arg;
  246.  
  247.   arg = FREAD;
  248.   (void) ioctl(0, TIOCFLUSH, (char *)&arg);   /* flush all input */
  249. #endif
  250. }
  251.  
  252.  
  253. #if 0
  254. /* this is no longer used anywhere */
  255. /* Flush buffer before input                -RAK-    */
  256. inkey_flush(x)
  257. char *x;
  258. {
  259.   if (!wizard1)  flush();
  260.   inkey(x);
  261. }
  262. #endif
  263.  
  264. /* Clears given line of text                -RAK-    */
  265. erase_line(row, col)
  266. int row;
  267. int col;
  268. {
  269.   move(row, col);
  270.   clrtoeol();
  271.   if (row == MSG_LINE)
  272.     msg_flag = FALSE;
  273. }
  274.  
  275.  
  276. /* Clears screen at given row, column                */
  277. clear_screen(row, col)
  278. int row, col;
  279. {
  280.   register int i;
  281.  
  282.   for (i = row; i < 23; i++)
  283.     used_line[i] = FALSE;
  284.   move(row, col);
  285.   clrtobot();
  286.   msg_flag = FALSE;
  287. }
  288.  
  289.  
  290. /* Clears entire screen, even if there are characters that curses
  291.    does not know about */
  292. really_clear_screen()
  293. {
  294.   register int i;
  295.  
  296.   for (i = 1; i < 23; i++)
  297.     used_line[i] = FALSE;
  298.   clear();
  299.   msg_flag = FALSE;
  300. }
  301.  
  302.  
  303. /* Outputs a line to a given interpolated y, x position    -RAK-    */
  304. print(str_buff, row, col)
  305. char *str_buff;
  306. int row;
  307. int col;
  308. {
  309.   row -= panel_row_prt;/* Real co-ords convert to screen positions */
  310.   col -= panel_col_prt;
  311.   used_line[row] = TRUE;
  312.   put_buffer(str_buff, row, col);
  313. }
  314.  
  315.  
  316. /* Outputs a line to a given y, x position        -RAK-    */
  317. prt(str_buff, row, col)
  318. char *str_buff;
  319. int row;
  320. int col;
  321. {
  322.   move(row, col);
  323.   clrtoeol();
  324.   put_buffer(str_buff, row, col);
  325. }
  326.  
  327.  
  328. /* move cursor to a given y, x position */
  329. move_cursor(row, col)
  330. int row, col;
  331. {
  332.   move (row, col);
  333. }
  334.  
  335.  
  336. /* Outputs message to top line of screen                */
  337. msg_print(str_buff)
  338. char *str_buff;
  339. {
  340.   register int old_len;
  341.   char in_char;
  342.   register int do_flush = 0;
  343.  
  344.   /* stop the character if s/he is in a run */
  345.   if (find_flag)
  346.     {
  347.       find_flag = FALSE;
  348.       move_light (char_row, char_col, char_row, char_col);
  349.     }
  350.  
  351.   if (msg_flag)
  352.     {
  353.       old_len = strlen(old_msg[last_message]) + 1;
  354.       put_buffer(" -more-", MSG_LINE, old_len);
  355.       /* let sigint handler know that we are waiting for a space */
  356.       wait_for_more = 1;
  357.       do
  358.     {
  359.       inkey(&in_char);
  360.     }
  361.       while ((in_char != ' ') && (in_char != '\033'));
  362.       wait_for_more = 0;
  363.       do_flush = 1;
  364.     }
  365.   move(MSG_LINE, 0);
  366.   clrtoeol();
  367.   if (do_flush)
  368.     put_qio();
  369.   put_buffer(str_buff, MSG_LINE, 0);
  370.  
  371.   if (!repeating_old_msg)
  372.     {
  373.       /* increment last message pointer */
  374.       last_message++;
  375.       if (last_message == SAVED_MSGS)
  376.     last_message = 0;
  377.       last_displayed_msg = last_message;
  378.       (void) strcpy(old_msg[last_message], str_buff);
  379.     }
  380.   msg_flag = TRUE;
  381. }
  382.  
  383.  
  384. /* repeat an old message */
  385. repeat_msg ()
  386. {
  387.   repeating_old_msg = 1;
  388.   /* if message still visible, decrement counter to display previous one */
  389.   if (save_msg_flag)
  390.     {
  391.       if (last_displayed_msg == 0)
  392.     last_displayed_msg = SAVED_MSGS;
  393.       last_displayed_msg--;
  394.       msg_flag = FALSE;
  395.       msg_print (old_msg[last_displayed_msg]);
  396.     }
  397.   else  /* display current message */
  398.     msg_print (old_msg[last_displayed_msg]);
  399.   repeating_old_msg = 0;
  400. }
  401.  
  402. /* Prompts (optional) and returns ord value of input char    */
  403. /* Function returns false if <ESCAPE> is input    */
  404. get_com(prompt, command)
  405. char *prompt;
  406. char *command;
  407. {
  408.   int com_val;
  409.   int res;
  410.  
  411.   if (strlen(prompt) > 1)
  412.     prt(prompt, 0, 0);
  413.   inkey(command);
  414.   com_val = (*command);
  415.   switch(com_val)
  416.     {
  417.     case 0: case 27:
  418.       res = FALSE;
  419.       break;
  420.     default:
  421.       res = TRUE;
  422.       break;
  423.     }
  424.   erase_line(MSG_LINE, 0);
  425.   msg_flag = FALSE;
  426.   return(res);
  427. }
  428.  
  429.  
  430. /* Gets a string terminated by <RETURN>                */
  431. /* Function returns false if <ESCAPE>, CNTL/(Y, C, Z) is input    */
  432. int get_string(in_str, row, column, slen)
  433. char *in_str;
  434. int row, column, slen;
  435. {
  436.   register int start_col, end_col, i;
  437.   char x;
  438.   char tmp[2];
  439.   int flag, abort;
  440.  
  441.   abort = FALSE;
  442.   flag  = FALSE;
  443.   in_str[0] = '\0';
  444.   tmp[1] = '\0';
  445.   put_buffer(pad(in_str, " ", slen), row, column);
  446.   put_buffer("\0", row, column);
  447.   start_col = column;
  448.   end_col = column + slen - 1;
  449.   do
  450.     {
  451.       inkey(&x);
  452.       switch(x)
  453.     {
  454.     case 27:
  455.       abort = TRUE;
  456.       break;
  457.     case 10: case 13:
  458.       flag  = TRUE;
  459.       break;
  460.     case 127: case 8:
  461.       if (column > start_col)
  462.         {
  463.           column--;
  464.           put_buffer(" \b", row, column);
  465.           in_str[strlen(in_str)-1] = '\0';
  466.         }
  467.       break;
  468.     default:
  469.       tmp[0] = x;
  470.       put_buffer(tmp, row, column);
  471.       (void) strcat(in_str, tmp);
  472.       column++;
  473.       if (column > end_col)
  474.         flag = TRUE;
  475.       break;
  476.     }
  477.     }
  478.   while ((!flag) && (!abort));
  479.   if (abort)
  480.     return(FALSE);
  481.   else
  482.     {            /* Remove trailing blanks    */
  483.       i = strlen(in_str);
  484.       if (i > 0)
  485.     {
  486.       while ((in_str[i] == ' ') && (i > 0))
  487.         i--;
  488.       in_str[i+1] = '\0';
  489.     }
  490.     }
  491.   return(TRUE);
  492. }
  493.  
  494.  
  495. /* Return integer value of hex string            -RAK-    */
  496. int get_hex_value(row, col, slen)
  497. int row, col, slen;
  498. {
  499.   vtype tmp_str;
  500.   int hex_value;
  501.  
  502.   hex_value = 0;
  503.   if (get_string(tmp_str, row, col, slen))
  504.     if (strlen(tmp_str) <= 8)
  505.       {
  506.     (void) sscanf(tmp_str, "%x", &hex_value);
  507.       }
  508.   return(hex_value);
  509. }
  510.  
  511.  
  512. /* Pauses for user response before returning        -RAK-    */
  513. pause_line(prt_line)
  514. int prt_line;
  515. {
  516.   char dummy;
  517.  
  518.   prt("[Press any key to continue]", prt_line, 23);
  519.   inkey(&dummy);
  520.   erase_line(23, 0);
  521. }
  522.  
  523.  
  524. /* Pauses for user response before returning        -RAK-    */
  525. /* NOTE: Delay is for players trying to roll up "perfect"    */
  526. /*    characters.  Make them wait a bit...            */
  527. pause_exit(prt_line, delay)
  528. int prt_line;
  529. int delay;
  530. {
  531.   char dummy;
  532.  
  533.   prt("[Press any key to continue, or Q to exit]", prt_line, 10);
  534.   inkey(&dummy);
  535.   switch(dummy)
  536.     {
  537.     case 'Q':
  538.       erase_line(prt_line, 0);
  539.       if (delay > 0)  (void) sleep((unsigned)delay);
  540.       exit_game();
  541.       break;
  542.     default:
  543.       break;
  544.     }
  545.   erase_line(prt_line, 0);
  546. }
  547.  
  548.  
  549. /* pad a string with fill characters to specified length */
  550. char *pad(string, fill, filllength)
  551. char *string;
  552. char *fill;
  553. int filllength;
  554. {
  555.   register int length, i;
  556.  
  557.   (void) strcpy(pad_output, string);
  558.   length = strlen(pad_output);
  559.   for (i = length; i < filllength; i++)
  560.     pad_output[i] = *fill;
  561.   pad_output[i] = '\0';
  562.   return(pad_output);
  563. }
  564.  
  565. int confirm()
  566. {
  567.   char command;
  568.  
  569.   if (get_com("Are you sure?", &command))
  570.     switch(command)
  571.       {
  572.       case 'y': case 'Y':
  573.     return TRUE;
  574.     
  575.       default:
  576.     return FALSE;
  577.       }
  578.   return FALSE;
  579. }
  580.  
  581.